package blog;

import blog.router.LoadRouter;
import blog.util.RsUtil;
import blog.util.StringUtils;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
import io.vertx.core.http.HttpHeaders;
import io.vertx.core.json.JsonObject;
import io.vertx.core.json.jackson.DatabindCodec;
import io.vertx.ext.auth.JWTOptions;
import io.vertx.ext.auth.jwt.JWTAuth;
import io.vertx.ext.auth.jwt.JWTAuthOptions;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.CorsHandler;
import io.vertx.ext.web.handler.JWTAuthHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.naming.AuthenticationException;

public class MainVerticle extends AbstractVerticle {

  private static final Logger LOGGER = LoggerFactory.getLogger(MainVerticle.class);

  @Override
  public void start(Promise<Void> startPromise) throws Exception {

    System.setProperty("vertx.logger-delegate-factory-class-name","io.vertx.core.logging.SLF4JLogDelegateFactory");

    String CONTEXT_PATH = "/blog-server";

    DatabindCodec.mapper().registerModule(new JavaTimeModule());  //解析Java8中到LocalDateTime

    Router router = Router.router(vertx);

    router.errorHandler(404,rc->rc.json(RsUtil.error(404,"找不到相应资源，请确认请求接口")));

    router.errorHandler(401,rc->rc.json(RsUtil.error(401,rc.failure().getMessage())));

    router.errorHandler(405,rc->rc.json(RsUtil.error(405,"请使用正确到请求方式请求该接口")));

    router.errorHandler(406,rc->rc.json(RsUtil.error(406,rc.failure().getMessage())));

//    router.errorHandler(500,rc->rc.json(RsUtil.error(500,"系统内部错误："+rc.failure().getMessage())));

    JWTAuthOptions authOptions = new JWTAuthOptions().setJWTOptions(new JWTOptions().setExpiresInSeconds(60 * 60 * 24));

    router.route().handler(CorsHandler.create("*").allowedHeader(HttpHeaderNames.AUTHORIZATION.toString()));

    JWTAuth auth = JWTAuth.create(vertx, authOptions);


    router.post(CONTEXT_PATH+"/login").handler(ctx-> {
        ctx.request().body(rb -> {
          if(rb.result().length() == 0){
            ctx.fail(401, new AuthenticationException("空的请求参数"));
            return;
          }
          JsonObject entries = rb.result().toJsonObject();
          if (entries.isEmpty()) {
            ctx.fail(401, new AuthenticationException("空的请求参数"));
          }else{
            String username = entries.getString("username");
            String password = entries.getString("password");
            if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
              ctx.fail(401, new AuthenticationException("用户名或密码不能为空"));
            }else{
              if ("huhailong".equals(username) && "hhl110120119".equals(password)) {
                ctx.response().putHeader(HttpHeaders.AUTHORIZATION, auth.generateToken(new JsonObject().put("sub", "huhailong")));
                ctx.json(RsUtil.success("登录成功"));
              } else {
                ctx.json(RsUtil.error(401, "用户名或密码错误"));
              }
            }
          }
        });
      });
    router.post().handler(JWTAuthHandler.create(auth));
    router.delete().handler(JWTAuthHandler.create(auth));
    router.put().handler(JWTAuthHandler.create(auth));

    LoadRouter.loadBlogContentRouter(router,CONTEXT_PATH).loadAll();

    vertx.createHttpServer().requestHandler(router).listen(8888, http -> {
      if (http.succeeded()) {
        startPromise.complete();
        LOGGER.info("Vert.x blog web server started on port {}",http.result().actualPort());
      } else {
        startPromise.fail(http.cause());
      }
    });
  }
}
